package com.neusoft.service.impl;

import com.neusoft.mapper.ClientWalletMapper;
import com.neusoft.mapper.CreditBillMapper;
import com.neusoft.service.ClientWalletService;
import com.neusoft.domain.TransactionRecordPO;
import com.neusoft.domain.TransactionType;
import com.neusoft.domain.VirtualWallet;
import com.neusoft.domain.VirtualWalletPO;
import com.neusoft.exception.InsufficientFundsException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.Date;

@Service
public class ClientWalletServiceImpl implements ClientWalletService {

    @Autowired
    private ClientWalletMapper walletClientMapper;
    @Autowired
    private CreditBillMapper creditBillMapper;

    @Override
    public void initializeWallet(Long userId) {
        VirtualWallet wallet = new VirtualWallet(
                null, // id 由数据库自动生成
                userId,
                BigDecimal.ZERO, // 初始余额为 0
                BigDecimal.valueOf(300), // 默认信用额度为 300
                BigDecimal.ZERO, // 初始已使用信用额度为 0
                BigDecimal.ZERO // 初始滞纳金余额为 0
        );
        walletClientMapper.insertWallet(wallet);
    }

    @Override
    public BigDecimal getCreditLimit(Long userId) {
        return walletClientMapper.getCreditLimit(userId);
    }

    @Override
    public VirtualWallet getWalletByUserId(Long userId) {
        return walletClientMapper.getWalletByUserId(userId);
    }

    @Override
    public void useCredit(Long userId, BigDecimal amount) throws InsufficientFundsException {
        // 获取钱包信息
        VirtualWalletPO walletPO = walletClientMapper.findById(userId);
        if (walletPO == null) {
            throw new InsufficientFundsException("钱包未找到");
        }

        VirtualWallet wallet = new VirtualWallet(
                walletPO.getId(),
                walletPO.getUserId(),
                walletPO.getBalance(),
                walletPO.getCreditLimit(),
                walletPO.getUsedCredit(),
                walletPO.getPenaltyAmount()
        );

        // 检查信用额度
        if (wallet.getBalance().compareTo(amount) < 0) {
            throw new InsufficientFundsException("信用额度不足");
        }

        // 使用信用额度并更新数据库
        wallet.useCredit(amount);
        walletClientMapper.updateWallet(walletPO.getId(), wallet.getBalance(), wallet.getUsedCredit());

        // 插入新的账单记录
        creditBillMapper.insertNewBill(walletPO.getId(), amount, new Date());
    }

    @Override
    @Transactional
    public void pay(Long userUserId, Long merchantUserId, BigDecimal amount) throws InsufficientFundsException {
        // 获取用户钱包信息
        VirtualWalletPO userWalletPO = walletClientMapper.findById(userUserId);
        if (userWalletPO == null) {
            throw new InsufficientFundsException("用户钱包未找到");
        }

        VirtualWallet userWallet = new VirtualWallet(
                userWalletPO.getId(),
                userWalletPO.getUserId(),
                userWalletPO.getBalance(),
                userWalletPO.getCreditLimit(),
                userWalletPO.getUsedCredit(),
                userWalletPO.getPenaltyAmount()
        );

        // 检查用户钱包余额是否足够
        if (userWallet.getBalance().compareTo(amount) < 0) {
            throw new InsufficientFundsException("用户余额不足，无法完成支付");
        }

        // 扣除用户的钱包余额
        userWallet.withdraw(amount);
        walletClientMapper.updateBalance(userWalletPO.getId(), userWallet.getBalance());

        // 获取商家钱包信息
        VirtualWalletPO merchantWalletPO = walletClientMapper.findById(merchantUserId);
        if (merchantWalletPO == null) {
            throw new InsufficientFundsException("商家钱包未找到");
        }

        VirtualWallet merchantWallet = new VirtualWallet(
                merchantWalletPO.getId(),
                merchantWalletPO.getUserId(),
                merchantWalletPO.getBalance(),
                merchantWalletPO.getCreditLimit(),
                merchantWalletPO.getUsedCredit(),
                merchantWalletPO.getPenaltyAmount()
        );

        // 更新商家钱包余额
        merchantWallet.deposit(amount);
        walletClientMapper.updateBalance(merchantWalletPO.getId(), merchantWallet.getBalance());

        // 记录交易流水
        TransactionRecordPO userTransaction = new TransactionRecordPO();
        userTransaction.setWalletId(userWalletPO.getId());
        userTransaction.setAmount(amount.negate()); // 负值表示支出
        userTransaction.setType(TransactionType.PAYMENT);
        userTransaction.setTimestamp(LocalDateTime.now());
        walletClientMapper.insertTransactionRecord(userTransaction);

        TransactionRecordPO merchantTransaction = new TransactionRecordPO();
        merchantTransaction.setWalletId(merchantWalletPO.getId());
        merchantTransaction.setAmount(amount); // 正值表示收入
        merchantTransaction.setType(TransactionType.RECEIPT); // 假设存在收款类型
        merchantTransaction.setTimestamp(LocalDateTime.now());
        walletClientMapper.insertTransactionRecord(merchantTransaction);
    }

    @Override
    public void deposit(Long userId, BigDecimal amount) {
        // 获取钱包信息
        VirtualWalletPO walletPO = walletClientMapper.findById(userId);
        if (walletPO == null) {
            throw new IllegalArgumentException("钱包未找到");
        }

        VirtualWallet wallet = new VirtualWallet(
                walletPO.getId(),
                walletPO.getUserId(),
                walletPO.getBalance(),
                walletPO.getCreditLimit(),
                walletPO.getUsedCredit(),
                walletPO.getPenaltyAmount()
        );

        // 更新钱包余额
        wallet.deposit(amount);
        BigDecimal balance=walletClientMapper.getBalance(userId).add(amount);
        walletClientMapper.updateBalance(walletPO.getId(), balance);

        // 记录交易流水
        TransactionRecordPO record = new TransactionRecordPO();
        record.setWalletId(walletPO.getId());
        record.setAmount(amount);
        record.setType(TransactionType.DEPOSIT);
        record.setTimestamp(LocalDateTime.now());
        walletClientMapper.insertTransactionRecord(record);
    }

    @Override
    public void withdraw(Long userId, BigDecimal amount) throws InsufficientFundsException {
        // 获取钱包信息
        VirtualWalletPO walletPO = walletClientMapper.findById(userId);
        if (walletPO == null) {
            throw new InsufficientFundsException("钱包未找到");
        }

        VirtualWallet wallet = new VirtualWallet(
                walletPO.getId(),
                walletPO.getUserId(),
                walletPO.getBalance(),
                walletPO.getCreditLimit(),
                walletPO.getUsedCredit(),
                walletPO.getPenaltyAmount()
        );

        // 检查余额是否足够
        if (wallet.getBalance().compareTo(amount) < 0) {
            throw new InsufficientFundsException("余额不足");
        }

        // 更新钱包余额
        wallet.withdraw(amount);
        walletClientMapper.updateBalance(walletPO.getId(), wallet.getBalance());

        // 记录交易流水
        TransactionRecordPO record = new TransactionRecordPO();
        record.setWalletId(walletPO.getId());
        record.setAmount(amount.negate()); // 负值表示支出
        record.setType(TransactionType.WITHDRAWAL);
        record.setTimestamp(LocalDateTime.now());
        walletClientMapper.insertTransactionRecord(record);
    }

    @Override
    public BigDecimal getBalance(Long userId) {
        VirtualWalletPO walletPO = walletClientMapper.findById(userId);
        if (walletPO == null) {
            throw new IllegalArgumentException("钱包未找到");
        }
        return walletPO.getBalance();
    }

    @Override
    public void transfer(Long fromUserId, Long toUserId, BigDecimal amount) throws InsufficientFundsException {
        this.withdraw(fromUserId, amount);
        this.deposit(toUserId, amount);
    }
}